# python3.6
import random
from paho.mqtt import client as mqtt_client
import ast  # 安全地解析字符串为字典
import re  # 正则表达式模块

data_dict = {'speed': [], 'torque': []}

broker = 'broker.emqx.io'
port = 1883
topic = "robot/ant/{robotLabel}"

client_id = f'python-mqtt-{random.randint(0, 100)}'

def connect_mqtt() -> mqtt_client:
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            print("Connected to MQTT Broker!")
        else:
            print("Failed to connect, return code %d\n", rc)

    client = mqtt_client.Client(client_id)
    client.on_connect = on_connect
    client.connect(broker, port)
    return client


def subscribe(client: mqtt_client):
    def on_message(client, userdata, msg):
        global data_dict
        # print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
        message = msg.payload.decode()
        # 这里假设消息是JSON格式，例如：{"speed": 10, "torque": 20}
        try:
            # 使用正则表达式提取消息中的字典部分
            match = re.search(r'\{.*\}', message)
            if match:
                dict_str = match.group(0).replace("'", '"')  # 将单引号替换为双引号
                data = ast.literal_eval(dict_str)  # 使用ast.literal_eval将字符串转换为字典
                speed = data.get('velocity actual value', 0)  # 获取速度值，默认为0
                torque = data.get('torque actual value', 0)  # 获取扭矩值，默认为0
                data_dict['speed'].append(speed)  # 将速度值添加到字典的speed列表中
                data_dict['torque'].append(torque)  # 将扭矩值添加到字典的torque列表中
                print(f"Received `{data_dict}` from  mqtt.q")
            else:
                print("No valid dictionary found in message")
        except (SyntaxError, ValueError):
            print("Failed to decode message as Python dictionary")  # 如果解析失败，打印错误信息
            print(f"Message content: {message}")  # 打印消息内容以检查其格式

    client.subscribe(topic)
    client.on_message = on_message

def run():
    client = connect_mqtt()
    subscribe(client)
    client.loop_forever()

if __name__ == '__main__':
    run()
